home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / JAVA_UTL / C2JAVA / C2J.ZIP / parser.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-17  |  27.3 KB  |  995 lines

  1. /*
  2. ##############################################################################
  3. #
  4. #  c2j          96/04/04   Chris Laffra
  5. #
  6. #  Copyright (c) 1995-1996 Morgan Stanley & Co., Inc. All Rights Reserved.
  7. #
  8. #  Permission to use, copy, modify, and distribute this software
  9. #  and its documentation for NON-COMMERCIAL purposes and without
  10. #  fee is hereby granted provided that this copyright notice
  11. #  appears in all copies. Please contact email: laffra@ms.com
  12. #  for further copyright and licensing information.
  13. #
  14. #  MORGAN STANLEY MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
  15. #  OF THIS SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  16. #  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. #  PARTICULAR PURPOSE, OR NON-INFRINGEMENT. MORGAN STANLEY SHALL NOT BE LIABLE
  18. #  FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  19. #  DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  20. #
  21. ##############################################################################
  22. */
  23.  
  24. ////////////////////////////////   See README file  //////////////////////////
  25.  
  26. #include <fstream.h>
  27. #include <iostream.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32.  
  33. #include "parser.hpp"
  34.  
  35. const char *PACKAGE= "SomePackage";    // change this to your package name
  36. const char *AUTHOR=  "SomeBody";    // change this to your name
  37. const char *COMPANY= "SomeCompany";    // change this to your company
  38.  
  39. int debug = 0;
  40.  
  41. char *PUBLIC = "public "; 
  42. char *PRIVATE = "private "; 
  43. char *PROTECTED = ""; 
  44. char *accessor = PROTECTED;
  45.  
  46. int  putback = 0;        // see getChar()
  47. char putback_char = 0;        // see getChar()
  48. int  lineno  = 0;        // the current line number
  49. int parse_methods = 0;        // program called with '-C' ?
  50. FILE *fout;            // our output
  51. FILE *statics;            // temporary file for storing global vars
  52. char initializer[2048];        // constructor initialize list (long enough?)
  53.  
  54.  
  55. // faster than strcmp(s1,s2):
  56. const char *_t1, *_t2;
  57. #define streq(s1, s2)  (_t1=s1,_t2=s2,_t1[0]==_t2[0] ? !strcmp(_t1+1,_t2+1) : 0)
  58. #define strneq(s1, s2) (!(streq(s1, s2)))
  59.  
  60. char getChar()
  61. {  
  62.   if (putback) {
  63.       putback = 0; 
  64.       return putback_char;
  65.   } 
  66.   else if (!cin.eof()) {
  67.     char c;
  68.     {
  69.       cin.unsetf(ios::skipws);
  70.       cin >> c;
  71.       if (c == '\r') return getChar();
  72.       if ((int)c < 0 || cin.eof()) { return EOF; }
  73.       if (c == '\n') lineno++;
  74.     }
  75.     if (fout != NULL) {
  76.       fprintf(fout,"%c", c);
  77.       if (c == '\n') fprintf(fout, "    ");
  78.     }
  79.     return c;
  80.   } else {
  81.     return EOF;
  82.   }
  83. }
  84.  
  85. void ungetChar(char c)
  86. {
  87.   putback = 1; 
  88.   putback_char = c;
  89. }
  90.  
  91. int isident(int c) { return isalnum(c) || c=='_'; }
  92.  
  93. void skipSpaces()
  94. {
  95.   char c;
  96.   do c = getChar(); while (isspace(c)) ;
  97.   ungetChar(c);
  98. }
  99.  
  100. const int BUFSIZE = 1024;
  101. const int MAXWORDSTACKSIZE = 32;
  102. char wordStack[MAXWORDSTACKSIZE][BUFSIZE];
  103. void initWordStack()
  104. {
  105.   for (int i=0; i<MAXWORDSTACKSIZE; i++) wordStack[i][0] = '\0';
  106. }
  107.  
  108. void printStack(int depth)
  109. {
  110.   for (int n=depth; n>0; n--) 
  111.     fprintf(stderr,"\t%d%s%s%s", n, "\t", wordStack[MAXWORDSTACKSIZE-n], "\n");
  112. }
  113.  
  114. void getClassNameFromStack(char *class_name,  int depth)
  115. {
  116.   strcpy(class_name,  "");
  117.   for (int n=depth; n<MAXWORDSTACKSIZE-depth-2; n+=3) {
  118.       if (strneq(wordStack[MAXWORDSTACKSIZE-(n+1)], ":") ||
  119.             strneq(wordStack[MAXWORDSTACKSIZE-(n+2)], ":")) 
  120.     break;
  121.   }
  122.   if (debug) printStack(n);
  123.   for (n; n>depth; n-=3)
  124.       strcat(class_name,  wordStack[MAXWORDSTACKSIZE-n]);
  125.   strcat(class_name,  wordStack[MAXWORDSTACKSIZE-depth]);
  126. }
  127.  
  128. int getWord(char *buf_, int bufsize_)
  129. {
  130.   skipSpaces();
  131.  
  132.   for (int n=0; n<bufsize_ && !cin.eof(); n++) {
  133.     if (n<bufsize_) buf_[n] = getChar();
  134.  
  135.     if (buf_[n] == '/') {                 // skip comments
  136.       if (n<bufsize_) buf_[++n] = getChar();
  137.       if (buf_[n] == '/') {                // the '//' form
  138.         do {
  139.           if (n<bufsize_) buf_[++n] = getChar();
  140.         } while (n<bufsize_ && !cin.eof() && buf_[n]!='\n');
  141.     return getWord(buf_, bufsize_);
  142.       }
  143.       else 
  144.       if (buf_[n] == '*') {                // the '/*' form
  145.     while (n<bufsize_ && !cin.eof()) {
  146.           do {
  147.             if (n<bufsize_) buf_[n] = getChar();
  148.           } while (n<bufsize_ && !cin.eof() && buf_[n]!='*');
  149.           if (n<bufsize_) buf_[n] = getChar();
  150.       if (buf_[n] == '/') break;
  151.     }
  152.     return getWord(buf_, bufsize_);
  153.       }
  154.       else {
  155.         if (n>0) ungetChar(buf_[n--]); 
  156.       }
  157.     }
  158.     if (buf_[n] == '#') {                 // skip preprocessor
  159.       char c;
  160.       do {
  161.     c = getChar(); 
  162.     if (c == '\\') { c = getChar(); c = getChar(); }
  163.       } while (!cin.eof() && c!='\n');
  164.       return getWord(buf_, bufsize_);
  165.     }
  166.  
  167.     if (buf_[n] == '\'') {                 // character constants
  168.       do {
  169.         if (n<bufsize_) buf_[++n] = getChar();
  170.     if (buf_[n] == '\\') {
  171.           if (n<bufsize_) buf_[++n] = getChar();
  172.           if (n<bufsize_) buf_[++n] = getChar();
  173.      }
  174.       } while (n<bufsize_ && !cin.eof() && buf_[n]!='\'');
  175.       buf_[n+1] = '\0';
  176.       return n+1;
  177.     }
  178.  
  179.     if (buf_[n] == '"') {                 // string constants
  180.       do {
  181.         if (n<bufsize_) buf_[++n] = getChar();
  182.     if (buf_[n] == '\\') {
  183.           if (n<bufsize_) buf_[++n] = getChar();
  184.           if (n<bufsize_) buf_[++n] = getChar();
  185.      }
  186.       } while (n<bufsize_ && !cin.eof() && buf_[n]!='"');
  187.       buf_[n+1] = '\0';
  188.       return n+1;
  189.     }
  190.  
  191.     if (!isident(buf_[n])) break;            // end of token
  192.   }
  193.   if (n>0) ungetChar(buf_[n--]);
  194.   buf_[n+1] = '\0';
  195.   for (int i=0; i<MAXWORDSTACKSIZE-1; i++)
  196.     strcpy(wordStack[i], wordStack[i+1]);
  197.   strcpy(wordStack[i], buf_);
  198.   return cin.eof() ? EOF : n+1;
  199. }
  200.  
  201. int skipWord()
  202. {
  203.   static char buf_[BUFSIZE];
  204.   return getWord(buf_, BUFSIZE);
  205. }
  206.  
  207. int findWord(char *word_to_find)
  208. {
  209.   if (debug) cerr << "findWord(" << word_to_find << ")\n";
  210.   char buf[256];
  211.   do {
  212.     if (getWord(buf, 256) == EOF) return 0;
  213.   } while (strneq(word_to_find, buf));
  214.   return 1;
  215. }  
  216.  
  217. int findAndDoNotSkipWord(char *word_to_find, char *dont_skip)
  218. {
  219.   if (debug) cerr << "findAndDoNotSkipWord(" << word_to_find << 
  220.                     "," << dont_skip << ")\n";
  221.   char buf[256];
  222.   do {
  223.     if (getWord(buf, 256) == EOF) return 0;
  224.     if (debug) cerr << "getWord() -> \"" << buf << "\"" << ")\n";
  225.     if (streq(buf, dont_skip)) return 0; 
  226.   } while (strneq(word_to_find, buf));
  227.   return 1;
  228. }  
  229.  
  230. int skipMatching(char *word_to_skip, char *word_to_find)
  231. {
  232.   if (debug) cerr << "skipMatching(" << word_to_skip << 
  233.                     "," << word_to_find << ") {\n";
  234.   char buf[256];
  235.   do {
  236.     if (getWord(buf, 256) == EOF) return 0;
  237.     if (debug) cerr << "      " << buf << "\n";
  238.     if (streq(word_to_skip, buf))
  239.     skipMatching(word_to_skip, word_to_find);
  240.   } while (strneq(word_to_find, buf));
  241.   if (debug) cerr << "}" << "\n";
  242.   return 1;
  243. }  
  244. char *MemberTypeNames[] = {
  245.   "Variable", "Enum", "Array", "Method", "InlinedMethod", 
  246.   "Constructor", "InlinedConstructor", 
  247.   "Destructor", "InlinedDestructor", 
  248.   "StaticMethod", "StaticInlinedMethod"
  249. };
  250.  
  251. ParmList* readParmList();
  252.  
  253. int isStaticMethod(const char *class_name, const char *method_name);
  254.  
  255. ClassRepresentation *class_info = 0;
  256.  
  257. //////////////////////////////////////////////////////////////////////
  258. //  PRINTING
  259. //////////////////////////////////////////////////////////////////////
  260.  
  261. void ClassMemberRepresentation::print(ClassRepresentation *c)
  262. {
  263.   if (next()) next()->print(c);
  264.   if (member_type() == ClassMemberRepresentation::Variable) {
  265.     printf("    %s%s%s%s", type(), " ", name(), ";");
  266.     printf("\n");
  267.   }
  268.   else 
  269.   if (member_type() == ClassMemberRepresentation::Enum) {
  270.     printf("    %s%s%s%s", type(), " ", name(), ";");
  271.     printf("\n");
  272.   }
  273.   else {
  274.     printf("\n");
  275.     printf("    /commentstart**%s", "\n");
  276.     printf("     * ");
  277.     printf("%s%s", ((name()[0] == '~') ? "finalize" : name()), "\n");
  278.     
  279.     printf("#include \"%s%s%s", c->name(), "__", name());
  280.     if (_parameters) 
  281.       _parameters->printTypes(stdout);
  282.     else
  283.       printf("_void");
  284.     printf("\"%s", "\n");
  285.  
  286.     printf("    %s%s", accessor(), "\n");
  287.  
  288.     printf("#include \"%s%s%s", c->name(), "__", name());
  289.     if (_parameters) 
  290.       _parameters->printTypes(stdout);
  291.     else
  292.       printf("_void");
  293.     printf("__body\"%s", "\n");
  294.   }
  295. }
  296.  
  297. void ClassRepresentation::print() { 
  298.   if (_is_super) return;
  299.  
  300.   printf("\n");
  301.   printf("/commentstart**\n");
  302.   printf(" * class %s%s", name(), "\n");
  303.   printf(" * \n");
  304.   printf(" * This code has been generated using c2j.\n");
  305.   printf(" * Courtesy of Morgan Stanley & Co., Inc.\n");
  306.   printf(" * Read general disclaimer distributed with c2j before");
  307.   printf(" using this code.\n");
  308.   printf(" * For information about c2j, send mail to laffra@ms.com\n");
  309.   printf(" * \n");
  310.   printf(" * Copyright 1995/1996, %s%s" , COMPANY,  " All rights reserved\n");
  311.   printf(" * @author %s%s", AUTHOR, "\n");
  312.   printf(" *commentend/\n");
  313.  
  314.   if (!nested())
  315.       printf("public ");
  316.   printf("class %s%s", name(), " ");
  317.  
  318.   if (super())
  319.       printf("extends %s", super()->name());
  320.   if (super() && super()->next()) {
  321.       printf(" implements %s", super()->next()->name());
  322.       if (super()->next()->next()) 
  323.       for (SuperClassRepresentation *s = super()->next()->next(); s; 
  324.                             s = s->next()) {
  325.         printf("[%s%s", s->name(), "]");
  326.         if (s->next() && s->name())
  327.           printf(", ");
  328.       }
  329.   }
  330.  
  331.   printf(" {\n");
  332.   if (members()) members()->print(this); 
  333.   printf("\n");
  334.   printf("#include \"__statics\"\n");
  335.   printf("};\n");
  336. }
  337.  
  338.  
  339. //////////////////////////////////////////////////////////////////////
  340.  
  341. void readClassBody(char *class_name);
  342.   
  343. ClassRepresentation *
  344. findClass(const char *class_name, int is_super_class)
  345. {
  346.   static ClassRepresentation *c_cache = 0;
  347.   static char cache_class_name[256];
  348.   if (c_cache && streq(class_name, cache_class_name)) return c_cache;
  349.   for (ClassRepresentation *c = class_info; c; c = c->next()) 
  350.     if (streq(c->name(), class_name)) {
  351.       c_cache = c;
  352.       strcpy(cache_class_name, class_name);
  353.       return c;
  354.     }
  355.   c = new ClassRepresentation(class_name, class_info, is_super_class);
  356.   class_info = c; 
  357.   return c;
  358. }
  359.  
  360. void setSuperClass(const char *class_name_, const char *super_class_name_)
  361. {
  362.   if (streq(super_class_name_, ",")) return;
  363.   if (debug) cerr << "setSuperClasses(" << class_name_ << ", "
  364.                       << super_class_name_ << ")\n";
  365.   ClassRepresentation *c1 = findClass(class_name_, 0);
  366.   ClassRepresentation *c2 = findClass(super_class_name_, 1);
  367.   c1->addSuperClass(c2);
  368. }
  369.  
  370. int readSuperClasses(const char *class_name_)
  371. {
  372.   if (debug) cerr << "readSuperClasses(" << class_name_ << ")\n";
  373.   char buf[256];
  374.   while (1) {
  375.     if (getWord(buf, 256) == EOF) return 0;
  376.     if (debug) cerr << "getWord() -> \"" << buf << "\"" << ")\n";
  377.     if (streq(buf,":"))        continue;
  378.     if (streq(buf,"public"))    continue;
  379.     if (streq(buf,"private"))   continue;
  380.     if (streq(buf,"protected")) continue;
  381.     if (streq(buf, "{")) break;
  382.     if (streq(buf, ";")) return 0; 
  383.     else setSuperClass(class_name_, buf);
  384.   }
  385.   return 1;
  386. }
  387.  
  388. void readMemberBody(char *class_name_, char *member_name_, char *type_,
  389.         ParmList **parameters_) 
  390. {
  391.   char file_name[BUFSIZE];
  392.  
  393.   strcpy(file_name, "__c2j_java__/");
  394.   strcat(file_name, class_name_);
  395.   strcat(file_name, "__");
  396.   strcat(file_name, member_name_);
  397.   if (*parameters_) 
  398.     (*parameters_)->printTypes(file_name); 
  399.  
  400.   fout = fopen(file_name,"w");    // in VisualC++ ofstream did not work!
  401.   if (*parameters_) 
  402.     (*parameters_)->printAsParms(fout);
  403.   if (strneq(type_, "void") && 
  404.         strneq(type_,":") &&
  405.         strneq(type_,";") &&
  406.         strneq(type_,"}") &&
  407.                     strcmp(class_name_, member_name_))
  408.     fprintf(fout,"     * @return %s\n", type_);
  409.   fprintf(fout,"     *commentend/\n");
  410.   fclose(fout);
  411.  
  412.   strcat(file_name, "__body");
  413.   fout = fopen(file_name, "w");
  414.   if (strneq(type_, ":") && strneq(type_,";") && strneq(type_,"}"))
  415.     fprintf(fout, "    %s ", type_);
  416.  
  417.   if (member_name_[0] == '~')
  418.     fprintf(fout,  "void finalize() {");
  419.   else {
  420.     fprintf(fout,  "%s(", member_name_);
  421.     if (*parameters_) 
  422.       (*parameters_)->printNames(fout);
  423.     fprintf(fout, ") {");
  424.   }
  425.  
  426.   fprintf(fout, " %s\n", initializer);
  427.   strcpy(initializer,"");
  428.  
  429.   skipMatching("{", "}"); 
  430.  
  431.   fclose(fout);
  432. }
  433.  
  434. int readMember(char *class_name_, 
  435.         ClassMemberRepresentation::Type *type,
  436.         char *name_, char *type_, int bufsize_,
  437.         ParmList **parameters_) 
  438. {
  439.   static int comma_seen = 0;
  440.  
  441.   *parameters_ = 0;
  442.  
  443.   if (debug) cerr << "readMember(" << class_name_ << 
  444.                     "," << name_ << 
  445.                     "," << type_ << ")\n";
  446.   char separator[BUFSIZE];
  447.   int is_static = 0;
  448.   name_[0] = '\0';
  449.   static int inside_enum = 0;
  450.  
  451.   if (comma_seen) {
  452.       if (debug) cerr << "comma seen, continue with type " << type_ << "\n";
  453.   }
  454.   else {
  455.       if (getWord(type_, bufsize_) ==  EOF) return 0;
  456.       if (debug) cerr << "first word=" << type_ << "\n";
  457.   }
  458.  
  459.   if (streq(type_,"public"))    { 
  460.     accessor = PUBLIC;
  461.     skipWord(); return 1; 
  462.   } 
  463.   else
  464.   if (streq(type_,"private"))   { 
  465.     accessor = PRIVATE;
  466.     skipWord(); return 1; 
  467.   } 
  468.   else
  469.   if (streq(type_,"protected")) { 
  470.     accessor = PROTECTED; 
  471.     skipWord(); return 1; 
  472.   } 
  473.   else
  474.   if (streq(type_,"enum")) {
  475.     if (debug) cerr << "enum " << type_ << "\n";
  476.     if (!findAndDoNotSkipWord("{", ";")) 
  477.       return 0;
  478.     if (getWord(type_, bufsize_) ==  EOF) return 0;
  479.     inside_enum = 1;
  480.   }
  481.   if (inside_enum) {
  482.     if (streq(type_, "}")) {    // matching {
  483.       inside_enum = 0;
  484.       return 1;
  485.     }
  486.     strcpy(name_, type_);
  487.     if (getWord(separator, bufsize_) ==  EOF) return 0;
  488.     if (streq(separator, "=")) {
  489.       if (getWord(separator, bufsize_) ==  EOF) return 0;
  490.       strcat(name_, " = ");
  491.       strcat(name_, separator);
  492.       if (getWord(separator, bufsize_) ==  EOF) return 0;
  493.     }
  494.     if (streq(separator, "}")) {    // matching {
  495.       inside_enum = 0;
  496.     }
  497.     strcpy(type_, "static final int");
  498.     if (debug) cerr << "enum " << name_ << "\n";
  499.     *type = ClassMemberRepresentation::Variable;
  500.     return 1;
  501.   }
  502.  
  503.   if (streq(type_,"{")) { skipMatching(type_, "}"); return 1; }
  504.  
  505.   // missing { ?
  506.   if (streq(type_,"}")) { ungetChar(type_[0]); comma_seen=0; return 0; } 
  507.  
  508.   if (streq(type_,";")) return 1;
  509.  
  510.   if (streq(type_,"class")) {
  511.     char name[256];
  512.     char nested_class_name[256];
  513.     if (getWord(nested_class_name, 256) == EOF) return 1;
  514.     if (debug) cerr << "nested_class_name=" << nested_class_name << "\n";
  515.     if (readSuperClasses(name)) {
  516.       strcpy(name, class_name_);
  517.       strcat(name, nested_class_name);
  518.       readClassBody(name);
  519.       findClass(name,0)->nested(1);
  520.       skipMatching("{", "}"); 
  521.       if (getWord(separator, bufsize_) == EOF) return 0; 
  522.       return 1;
  523.     }
  524.   }
  525.   if (getWord(name_, bufsize_) ==  EOF) return 0;
  526.   if (debug) cerr << "name=" << name_ << "\n";
  527.  
  528.   if (streq(name_,"(")) { 
  529.     strcpy(name_, type_);
  530.  
  531.     if (debug) cerr << "before constructor " << "\n";
  532.     *parameters_ = readParmList();
  533.  
  534.     if (findAndDoNotSkipWord("{", ";")) {
  535.       if (streq(name_, class_name_)) {
  536.         *type = ClassMemberRepresentation::InlinedConstructor;
  537.     readMemberBody(name_, name_, "", parameters_); 
  538.       }
  539.       else {
  540.     readMemberBody(name_, name_, "", parameters_); 
  541.         return 1;
  542.       }
  543.     }
  544.     else
  545.       *type = ClassMemberRepresentation::Constructor;
  546.  
  547.     if (debug) cerr << "found constructor " << "\n";
  548.     return 1;
  549.   }
  550.  
  551.  
  552.   if (streq(type_,"~")) { 
  553.     strcat(type_, name_);
  554.     strcpy(name_, type_);
  555.     strcpy(type_, "");
  556.     *parameters_ = readParmList();
  557.     if (findAndDoNotSkipWord("{", ";")) {
  558.       *type = ClassMemberRepresentation::InlinedDestructor;
  559.       readMemberBody(name_+1, name_, "", parameters_); 
  560.     }
  561.     else
  562.       *type = ClassMemberRepresentation::Destructor;
  563.  
  564.     if (debug) cerr << "found destructor " << "\n";
  565.     return 1;
  566.   }
  567.   if (streq(name_,"{")) { skipMatching("{", "}"); return 1; }
  568.   if (streq(name_,"}")) { ungetChar('}'); comma_seen=0; return 0; }
  569.   if (streq(name_,";")) { ungetChar(';'); return 1; }
  570.  
  571.   *type = ClassMemberRepresentation::Variable;
  572.   for (;;) {
  573.     if (streq(type_,"static")) is_static = 1;
  574.     if (getWord(separator, bufsize_) == EOF) return 0; 
  575.     if (debug) cerr << "separator=" << separator << "\n";
  576.  
  577.     if (streq(separator,"}")) { ungetChar('}'); comma_seen=0; return 0; }
  578.     if (streq(separator,"{")) {    // }
  579.       skipMatching("{", "}"); 
  580.     }
  581.     if (streq(separator,"[")) {
  582.       skipMatching("[", "]"); 
  583.       *type = ClassMemberRepresentation::Array;
  584.       break; 
  585.     }
  586.     if (streq(separator,"(")) {         // read member parameters
  587.  
  588.       if (debug) cerr << "seen start of function" << "\n";
  589.       if (debug) cerr << "before readParmList " << "\n";
  590.       *parameters_ = readParmList();
  591.       if (debug)
  592.     cerr << "after readParmList " << endl << "found a method" << "\n";
  593.  
  594.       if (findAndDoNotSkipWord("{", ";")) {    // }
  595.         if (streq(name_,"="))      is_static = 1;
  596.         if (streq(name_,"!="))     is_static = 1;
  597.         if (streq(name_,"=="))     is_static = 1;
  598.         if (streq(name_,"new"))    is_static = 1;
  599.         if (streq(name_,"delete")) is_static = 1;
  600.  
  601.         readMemberBody(class_name_, name_, type_, parameters_); 
  602.  
  603.         *type = (is_static) ? ClassMemberRepresentation::StaticInlinedMethod
  604.                 : ClassMemberRepresentation::InlinedMethod;
  605.       }
  606.       else {
  607.         *type = (is_static) ? ClassMemberRepresentation::StaticMethod
  608.                 : ClassMemberRepresentation::Method;
  609.       }
  610.       if (debug) cerr << "end of function" << "\n";
  611.       break; 
  612.     }    
  613.     if (streq(separator,";")) break;
  614.     if (streq(separator,",")) {
  615.         comma_seen = 1;
  616.     return 1;
  617.     }
  618.  
  619.     else if (streq(name_,"*")) ; //strcat(type_, name_);
  620.     else if (streq(name_,"&")) ; //strcat(type_, name_);
  621.     else strncpy(type_, name_, bufsize_);
  622.     strncpy(name_, separator, bufsize_);
  623.   }
  624.   if (streq(type_,":")) strcpy(type_, "");
  625.   return 1;
  626. }
  627.  
  628. ClassMemberRepresentation *
  629. findMember(const char *class_name, const char *method_name)
  630. {
  631.   ClassRepresentation *c = findClass(class_name, 0);
  632.   if (c) 
  633.     for (ClassMemberRepresentation *m = c->members(); m; m = m->next())
  634.       if (streq(m->name(), method_name)) return m;
  635.   return 0;
  636. }
  637.  
  638. int isStaticMethod(const char *class_name, const char *method_name)
  639. {
  640.   if (streq(method_name,"="))      return 1;
  641.   if (streq(method_name,"!="))     return 1;
  642.   if (streq(method_name,"=="))     return 1;
  643.   if (streq(method_name,"new"))    return 1;
  644.   if (streq(method_name,"delete")) return 1;
  645.   ClassMemberRepresentation *m = findMember(class_name, method_name);
  646.   if (!m) {
  647.     return 1;
  648.   }
  649.   return (m->member_type()==ClassMemberRepresentation::StaticMethod ||
  650.           m->member_type()==ClassMemberRepresentation::StaticInlinedMethod);
  651. }
  652.  
  653. int is_a_valid_name(char *name)
  654. {
  655.   return (name && name[0] && name[0]!=';');
  656. }
  657.  
  658. void readClassBody(char *class_name)
  659. {
  660.   if (debug) cerr << "readClassBody " << class_name << "\n";
  661.  
  662.   ClassRepresentation *c = findClass(class_name, 0);
  663.   char name[256];
  664.   char type[256];
  665.   ClassMemberRepresentation::Type member_type;
  666.   ClassMemberRepresentation *mdouble = 0;
  667.   ClassMemberRepresentation *m = 0;
  668.   ParmList *parms;
  669.   while (readMember(class_name, &member_type, name, type, 256, &parms))
  670.     if (is_a_valid_name(name)) {
  671.       m = new ClassMemberRepresentation(type, name, 
  672.                 member_type, m, parms, accessor);
  673.       c->members(m); 
  674.       if (m->member_type()==ClassMemberRepresentation::Method)
  675.         for (mdouble = c->members(); mdouble; mdouble = mdouble->next())
  676.           if ((m->member_type()==ClassMemberRepresentation::StaticMethod ||
  677.                m->member_type()==ClassMemberRepresentation::Method) &&
  678.               streq(m->name(), mdouble->name()) &&
  679.               streq(m->type(), mdouble->type())) {
  680.         // cannot cope with overloaded functions yet.
  681.         m->member_type(ClassMemberRepresentation::StaticMethod);
  682.       }
  683.     }
  684. }
  685.  
  686. void ParmList::Delete()
  687. {
  688.   if (next()) next()->Delete();
  689.   delete this;
  690. }
  691.  
  692. void ParmList::printNames(FILE *fout)
  693. {
  694.   if (!name()[0] || streq(name(), "void")) return;
  695.   if (next() && next()->type()[0]) {
  696.     next()->printNames(fout);
  697.   }
  698.   if (next() && next()->type()[0])
  699.     fprintf(fout, ", ");
  700.   if (strneq(name(),"0"))
  701.     fprintf(fout, "%s %s", type(), name());
  702. }
  703.  
  704. void ParmList::printAsParms(FILE *fout)
  705. {
  706.   if (!name()[0] || streq(name(), "void")) return;
  707.   if (next() && next()->type()[0]) {
  708.     next()->printAsParms(fout);
  709.   }
  710.   if (strneq(name(),"0"))
  711.     fprintf(fout, "     * @param %s\n", name());
  712. }
  713.  
  714. void ParmList::printTypes(char *buf)
  715. {
  716.   if (!type()[0]) return;
  717.   if (next())
  718.     next()->printTypes(buf);
  719.   strcat(buf, "_");
  720.   if (streq(type(),"unsigned"))
  721.     strcat(buf, "int");
  722.   else
  723.     strcat(buf, type());
  724. }
  725.  
  726. void ParmList::printTypes(FILE *fout)
  727. {
  728.   if (!type()[0]) return;
  729.   if (next())
  730.     next()->printTypes(fout);
  731.   fprintf(fout, "_");
  732.   if (streq(type(),"unsigned"))
  733.     fprintf(fout, "int");
  734.   else
  735.     fprintf(fout, "%s", type());
  736. }
  737.  
  738. ParmList* readParmList()
  739. {
  740.   if (debug) cerr << "enter readParmList()" << "\n";
  741.  
  742.   char token[256];
  743.   ParmList *list = new ParmList("","",(ParmList*)0);
  744.   char *type;
  745.   char *name;
  746.   do {
  747.     if (getWord(token, 256) == EOF) return 0;
  748.  
  749.     if (streq(token, ",") || streq(token, ")")) {
  750.       type = wordStack[MAXWORDSTACKSIZE-3];
  751.       name = wordStack[MAXWORDSTACKSIZE-2];
  752.  
  753.       if (streq(type,",") || streq(type,"(")) {
  754.           type = wordStack[MAXWORDSTACKSIZE-2];
  755.           name = "";
  756.       }
  757.  
  758.       if (streq(type,":")) {
  759.           type = wordStack[MAXWORDSTACKSIZE-2];
  760.           name = "";
  761.       }
  762.  
  763.       if (streq(type,"*")) {
  764.           type = wordStack[MAXWORDSTACKSIZE-4];
  765.           name = wordStack[MAXWORDSTACKSIZE-2];
  766.       }
  767.  
  768.       if (streq(type,"&")) {
  769.           type = wordStack[MAXWORDSTACKSIZE-4];
  770.           name = wordStack[MAXWORDSTACKSIZE-2];
  771.       }
  772.  
  773.       if (streq(type,"=")) {
  774.           type = wordStack[MAXWORDSTACKSIZE-5];
  775.           name = wordStack[MAXWORDSTACKSIZE-4];
  776.       }
  777.  
  778.       if (streq(name, "&")) 
  779.     strcpy(name, "dummy_");
  780.       if (streq(name, "*")) 
  781.     strcpy(name, "dummy_");
  782.  
  783.       if (streq("unsigned", wordStack[MAXWORDSTACKSIZE-4]) &&
  784.             (streq(type, "long") || streq(type, "short") ||
  785.              streq(type, "int") || streq(type, "char"))) {
  786.         type = wordStack[MAXWORDSTACKSIZE-4];
  787.     strcat(type, "_");
  788.     strcat(type, wordStack[MAXWORDSTACKSIZE-3]);
  789.       }
  790.  
  791.       if (streq(type, "unsigned") && 
  792.             (streq(name, "long") || streq(name, "short") ||
  793.              streq(name, "int") || streq(name, "char"))) {
  794.     strcat(type, "_");
  795.     strcat(type, name);
  796.     strcpy(name, "");
  797.         list = new ParmList(type, "", list);
  798.       }
  799.       else
  800.       if (streq(name, "void")) 
  801.         list = new ParmList(name, "", list);
  802.       else
  803.       if (isident(name[0]))
  804.         list = new ParmList(type, name, list);
  805.       else
  806.         if (name[0] == '(') 
  807.           list = new ParmList("", "", list);
  808.     else
  809.           list = new ParmList(type, "0", list);
  810.     }
  811.   } while (!streq(token, "{") && !streq(token, ";") && !streq(token, ")"));
  812.  
  813.   if (debug) { 
  814.     cerr << "\ttype = \"" << type << "\"" ; 
  815.     cerr << "\tname = \"" << name << "\"" << "\n"; 
  816.   }
  817.  
  818.   if (streq(token, ")")) {
  819.     if (getWord(token, 256) == EOF) return 0;
  820.     if (streq(token, "const")) {
  821.       if (getWord(token, 256) == EOF) return 0;
  822.     }
  823.   }
  824.  
  825.   //
  826.   // read initializer list
  827.   //
  828.   if (streq(token, ":")) {
  829.     if (getWord(token, 256) == EOF) return 0;
  830.     strcpy(initializer, "\n\t");
  831.     int superConstructorCall = 0;
  832.     while (!streq(token, "{") && !streq(token, ";")) {
  833.       if (token[0]>='A'&&token[0]<='Z') {
  834.           strcat(initializer, "super");
  835.           superConstructorCall = 1;
  836.       }
  837.       else
  838.       if (superConstructorCall) {
  839.           if (streq(token, "(")) strcat(initializer, "(");
  840.           else if (streq(token, ")")) {
  841.              strcat(initializer, ");\n\t");
  842.              superConstructorCall = 1;
  843.           }
  844.           else if (streq(token, ",")) strcat(initializer, ",");
  845.           else strcat(initializer, token);
  846.       }
  847.       else {
  848.           if (streq(token, "(")) strcat(initializer, "=");
  849.           else if (streq(token, ")")) strcat(initializer, ";\n\t");
  850.           else if (streq(token, ",")) strcat(initializer, "");
  851.           else strcat(initializer, token);
  852.       }
  853.       if (getWord(token, 256) == EOF) return 0;
  854.     }
  855.   }
  856.  
  857.   ungetChar(token[0]);
  858.   if (debug) cerr << "leave readParmList()" << "\n";
  859.   return list;
  860. }
  861.  
  862. int readClass()
  863. {
  864.   if (debug) cerr << "readClass() {" << "\n";
  865.   char token[256];
  866.   char class_name[256];
  867.   for (;;) {
  868.     if (getWord(token, 256) == EOF) return 0;
  869.  
  870.     if (streq(token, "class")) {    // start of class definition
  871.       if (getWord(class_name, 256) == EOF) return 0;
  872.       if (readSuperClasses(class_name)) {
  873.  
  874.     readClassBody(class_name);    // will read unto }
  875.         if (debug) cerr << "}" << "\n";
  876.     return 1;
  877.       }
  878.       continue;
  879.     }
  880.     
  881.     char type[256];
  882.     char class_name[256];
  883.     char method_name[256];
  884.     method_name[0] = '\0';
  885.     class_name[0] = '\0';
  886.     if (streq(token, "(")) {        // beginning of formal parameter list?
  887.  
  888.       if (streq(wordStack[MAXWORDSTACKSIZE-3], ":") &&
  889.           streq(wordStack[MAXWORDSTACKSIZE-4], ":")) {
  890.         getClassNameFromStack(class_name,  5);
  891.         strcpy(method_name, wordStack[MAXWORDSTACKSIZE-2]);
  892.         strcpy(type, wordStack[MAXWORDSTACKSIZE-6]);
  893.     if (streq(type,"*") || streq(type,"&"))
  894.           strcpy(type, wordStack[MAXWORDSTACKSIZE-7]);
  895.       }
  896.       else 
  897.       if (streq(wordStack[MAXWORDSTACKSIZE-3], "~") &&
  898.           streq(wordStack[MAXWORDSTACKSIZE-4], ":") &&
  899.           streq(wordStack[MAXWORDSTACKSIZE-5], ":")) {
  900.         getClassNameFromStack(class_name,  6);
  901.         strcpy(type, wordStack[MAXWORDSTACKSIZE-7]);
  902.     if (streq(type,"*") || streq(type,"&"))
  903.           strcpy(type, wordStack[MAXWORDSTACKSIZE-8]);
  904.         strcpy(method_name, "~");
  905.         strcat(method_name, wordStack[MAXWORDSTACKSIZE-2]);
  906.       }
  907.  
  908.       if (class_name[0]) {
  909.     //
  910.     // start of a class method 
  911.     //
  912.  
  913.         if (debug) cerr << "start of class method" << "\n";
  914.         ParmList *p = readParmList();
  915.  
  916.     char token[128];
  917.         if (getWord(token, 128) == EOF) return 0;
  918.         
  919.         if (p && streq(token,"{")) {    // found a body
  920.       if (parse_methods) {
  921.         readMemberBody(class_name, method_name, type, &p); 
  922.         if (getWord(token, 128) == EOF) return 0;
  923.       }
  924.       else 
  925.             skipMatching("{", "}"); // look for }
  926.         }
  927.         if (debug) cerr << "end of class method" << "\n";
  928.       }
  929.       else {
  930.     //
  931.     // start of a global function 
  932.     //
  933.         if (debug) cerr << "start of global function" << "\n";
  934.         strcpy(method_name, wordStack[MAXWORDSTACKSIZE-2]);
  935.         ParmList *p = readParmList();
  936.     char token[128];
  937.         if (getWord(token, 128) == EOF) return 0;
  938.         if (streq(token,"{")) {    // found a body
  939.       if (p) {
  940.         p->printNames(stdout);
  941.         p->Delete();
  942.       }
  943.       skipMatching("{", "}"); // look for }
  944.     }
  945.         else
  946.       if (getWord(token, 256) == EOF) return 0;
  947.       }
  948.     }
  949.     if (parse_methods && streq(token, ";")) {        // end of a declaration
  950.       if (debug) cerr << "start of static declaration" << "\n";
  951.       if (debug) printStack(10);
  952.       for (int i=0; i<MAXWORDSTACKSIZE; i++) {
  953.         if (streq(wordStack[MAXWORDSTACKSIZE-i], "static")) {
  954.       fprintf(statics, "    final ");
  955.           for (int j=i; j>=0; j--) {
  956.         fprintf(statics, "%s ", wordStack[MAXWORDSTACKSIZE-j] );
  957.         if (debug) cerr << wordStack[MAXWORDSTACKSIZE-j] << " ";
  958.       }
  959.       fprintf(statics,"\n");
  960.       if (debug) cerr << "\n";
  961.     }
  962.       }
  963.       if (debug) cerr << "end of declaration" << "\n";
  964.     }
  965.   }
  966.   if (debug) cerr << "}" << "\n";
  967.   return 0;
  968. }
  969.  
  970.  
  971. int main(int argc,char **argv)
  972. {
  973.   if (argc == 2) {
  974.     if (argv[1][0] == '-' && argv[1][1] == 'C')
  975.        parse_methods = 1;
  976.   } 
  977.   else if (argc == 1) { } 
  978.   else { 
  979.     cerr << "usage: parser <filename>" << "\n"; 
  980.     return 1; 
  981.   }
  982.  
  983.   if (parse_methods) 
  984.     statics = fopen("__c2j_java__/__statics", "w");
  985.   else 
  986.     printf("package %s %s", PACKAGE , ";\n");
  987.  
  988.   while (readClass()) ;
  989.  
  990.   if (!parse_methods)
  991.     for (ClassRepresentation *c = class_info; c; c = c->next())
  992.       c->print();
  993.   return 0;
  994. }
  995.